#include "formcamera.h"
#include "ui_formcamera.h"
#include <QMessageBox>

#include <algorithm>
#include "Path.h"

#include "FileVideoSource.h"
#include "DirVideoSource.h"
#include "VideoCaptureSource.h"

#include "AppConfig.h"
#include "TStringUtil.h"

FormCamera::FormCamera(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FormCamera),
    m_rate(3)
{
    ui->setupUi(this);

    setupUI();
}

FormCamera::~FormCamera()
{
	stop();

    delete ui;
}

void FormCamera::setCamera(Camera::DeviceList& deviceList)
{
    m_deviceList = deviceList;
}


void FormCamera::start()
{
    stop();

    QLabel* videoLabels[] =
    {
        ui->labelVideo,
        ui->labelVideo_2,
        ui->labelVideo_3
    };

    HistogramWidget* statusWidgets[] =
    {
        ui->widgetStatus,
        ui->widgetStatus_2,
        ui->widgetStatus_3
    };

	std::string filepath = getParamsPath();
	HeadCounter::Params params;
	HeadCounter::load(filepath.c_str(), params);

    size_t maxCount = std::min((size_t)3, m_deviceList.size());
    for (size_t i = 0; i < m_deviceList.size(); i ++)
    {
        CameraCounterPtr counter(new CameraCounter());
        counter->setCamera(m_deviceList[i]);
        counter->setRate(m_rate);
        counter->setupUI(videoLabels[i], statusWidgets[i]);
		counter->counterParams() = params;

		connect(counter.get(), &CameraCounter::countResult, this, &FormCamera::onCountResult);

        counter->start();

        m_cameraCounters.push_back(counter);
    }
}

void FormCamera::stop()
{
    for (auto counter : m_cameraCounters)
    {
        counter->stop();
    }

    m_cameraCounters.clear();
}

bool FormCamera::isStarted()
{
    return m_cameraCounters.size() > 0;
}

void FormCamera::resizeEvent(QResizeEvent *event)
{
    resizeCarriage();
}

void FormCamera::setRate(int fps)
{
	m_rate = fps;
}

void FormCamera::setupUI()
{
    std::string workdir = comn::Path::getWorkDir();
    std::string imagePath = comn::Path::join(workdir, "Carriage.png");
    if (comn::Path::exist(imagePath))
    {
        QPixmap pixmap(imagePath.c_str());
        ui->labelCarriage->setPixmap(pixmap);
    }

    resizeCarriage();
}

void FormCamera::resizeCarriage()
{
    QRect rc = ui->frame->rect();
    ui->labelCarriage->setGeometry(rc);

    QWidget* statusWidgets[] =
    {
        ui->widgetStatus,
        ui->widgetStatus_2,
        ui->widgetStatus_3
    };

    size_t count = sizeof(statusWidgets)/sizeof(statusWidgets[0]);
    for (size_t i = 0; i < count; i ++)
    {
        int segWidth = rc.width() / 3;
        int left = rc.left() + (i) * segWidth;
        int right = left + segWidth;

        int width = 120;
        if (segWidth > width)
        {
            left += (segWidth - width)/2;
            right = left + width;
        }
        else
        {
            width = segWidth;
        }

		int top = rc.top() + rc.height() / 2;

        QRect rcStatus(left, top, width, rc.height()/2);
        statusWidgets[i]->setGeometry(rcStatus);
    }
}


QColor FormCamera::getStatusColor(int status)
{
    if (status == CarriageValue::kEmpty)
    {
        return QColor(0, 0, 255);
    }
    else if (status == CarriageValue::kFull)
    {
        return QColor(255, 255, 0);
    }
    else if (status == CarriageValue::kCrowd)
    {
        return QColor(255, 128, 0);
    }
    return QColor(255, 0, 0);
}

void FormCamera::onCountResult(int index, int count, int status, bool exception)
{
    showCountResult(index, count, status, exception);

    emit countResult(index, count, status, exception);
}

void FormCamera::showCountResult(int index, int count, int status, bool exception)
{
    QLabel* labels[] =
    {
        ui->labelException,
        ui->labelException_2,
        ui->labelException_3
    };

    std::string text = exception ? "人员异常移动." : "";
    labels[index]->setText(text.c_str());

}

std::string FormCamera::getParamsPath()
{
	std::string filepath = comn::Path::getWorkDir();
	filepath = comn::Path::join(filepath, "HeadCounter.ini");
	return filepath;
}